#include "mqttmanager.h"
#include <QDebug>

MqttManager::MqttManager(QObject *parent)
    : QObject(parent)
    , m_socket(nullptr)
    , m_heartbeatTimer(nullptr)
    , m_reconnectTimer(nullptr)
    , m_isManualDisconnect(false)
    , m_sentCount(0)
    , m_receivedCount(0)
{
    // 创建TCP Socket
    m_socket = new QTcpSocket(this);
    
    // 连接信号
    connect(m_socket, &QTcpSocket::connected, this, &MqttManager::onConnected);
    connect(m_socket, &QTcpSocket::disconnected, this, &MqttManager::onDisconnected);
    connect(m_socket, &QTcpSocket::readyRead, this, &MqttManager::onReadyRead);
    connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
            this, &MqttManager::onError);
    
    // 创建心跳定时器
    m_heartbeatTimer = new QTimer(this);
    connect(m_heartbeatTimer, &QTimer::timeout, this, &MqttManager::onHeartbeatTimeout);
    
    // 创建重连定时器
    m_reconnectTimer = new QTimer(this);
    connect(m_reconnectTimer, &QTimer::timeout, this, &MqttManager::onReconnectTimeout);
}

MqttManager::~MqttManager()
{
    disconnectFromServer();
}

bool MqttManager::connectToServer(const MqttConfig &config)
{
    if (isConnected()) {
        m_lastError = "已经连接到服务器";
        return false;
    }
    
    m_config = config;
    m_isManualDisconnect = false;
    
    qDebug() << "连接到巴法云服务器:" << config.serverHost << ":" << config.serverPort;
    
    m_socket->connectToHost(config.serverHost, config.serverPort);
    
    return true;
}

void MqttManager::disconnectFromServer()
{
    m_isManualDisconnect = true;
    stopHeartbeat();
    stopReconnect();
    
    if (m_socket->state() != QAbstractSocket::UnconnectedState) {
        m_socket->disconnectFromHost();
        if (m_socket->state() != QAbstractSocket::UnconnectedState) {
            m_socket->waitForDisconnected(1000);
        }
    }
    
    m_subscribedTopics.clear();
}

bool MqttManager::isConnected() const
{
    return m_socket && m_socket->state() == QAbstractSocket::ConnectedState;
}

bool MqttManager::subscribeTopic(const QString &topic)
{
    return subscribeTopics(QStringList() << topic);
}

bool MqttManager::subscribeTopics(const QStringList &topics)
{
    if (!isConnected()) {
        m_lastError = "未连接到服务器";
        return false;
    }
    
    if (topics.isEmpty() || topics.size() > 8) {
        m_lastError = "主题数量必须在1-8之间";
        return false;
    }
    
    QString cmd = buildSubscribeCmd(topics);
    sendCommand(cmd);
    
    return true;
}

bool MqttManager::publishMessage(const QString &topic, const QString &msg)
{
    if (!isConnected()) {
        m_lastError = "未连接到服务器";
        return false;
    }
    
    QString cmd = buildPublishCmd(topic, msg);
    sendCommand(cmd);
    
    return true;
}

bool MqttManager::publishWithSet(const QString &topic, const QString &msg)
{
    return publishMessage(topic + "/set", msg);
}

bool MqttManager::publishWithUp(const QString &topic, const QString &msg)
{
    return publishMessage(topic + "/up", msg);
}

bool MqttManager::setFanMode(bool manual)
{
    m_config.manualMode = manual;
    QString msg = m_config.getModeMessage();
    
    qDebug() << "设置风扇模式:" << (manual ? "手动(M1)" : "自动(M0)");
    
    bool result = publishMessage(m_config.fanTopic, msg);
    if (result) {
        emit fanModeChanged(manual);
    }
    
    return result;
}

bool MqttManager::setFanSpeed(int speed)
{
    if (speed < 0 || speed > 3) {
        m_lastError = "风扇档位必须在0-3之间";
        return false;
    }
    
    m_config.fanSpeed = speed;
    QString msg = m_config.getFanSpeedMessage();
    
    qDebug() << "设置风扇档位:" << msg;
    
    bool result = publishMessage(m_config.fanTopic, msg);
    if (result) {
        emit fanSpeedChanged(speed);
    }
    
    return result;
}

bool MqttManager::publishTemperature(double temp)
{
    m_config.temperature = temp;
    QString msg = m_config.getTemperatureMessage();
    
    qDebug() << "发布温度数据:" << msg << "°C";
    
    return publishMessage(m_config.tempTopic, msg);
}

bool MqttManager::getHistoryMessage(const QString &topic)
{
    if (!isConnected()) {
        m_lastError = "未连接到服务器";
        return false;
    }
    
    QString cmd = buildHistoryCmd(topic);
    sendCommand(cmd);
    
    return true;
}

bool MqttManager::requestServerTime(int type)
{
    if (!isConnected()) {
        m_lastError = "未连接到服务器";
        return false;
    }
    
    QString cmd = buildTimeCmd(type);
    sendCommand(cmd);
    
    return true;
}

QString MqttManager::getConnectionStatus() const
{
    switch (m_socket->state()) {
        case QAbstractSocket::UnconnectedState:
            return "未连接";
        case QAbstractSocket::HostLookupState:
            return "查找主机...";
        case QAbstractSocket::ConnectingState:
            return "连接中...";
        case QAbstractSocket::ConnectedState:
            return "已连接";
        case QAbstractSocket::BoundState:
            return "已绑定";
        case QAbstractSocket::ClosingState:
            return "关闭中...";
        default:
            return "未知状态";
    }
}

void MqttManager::clearStatistics()
{
    m_sentCount = 0;
    m_receivedCount = 0;
    emit statisticsUpdated(m_sentCount, m_receivedCount);
}

// Private slots implementation

void MqttManager::onConnected()
{
    qDebug() << "已连接到巴法云服务器";
    m_lastError.clear();
    
    emit connected();
    emit connectionStatusChanged(getConnectionStatus());
    
    // 启动心跳
    startHeartbeat();
    
    // 自动订阅配置的主题
    QStringList topics;
    if (!m_config.fanTopic.isEmpty()) {
        topics << m_config.fanTopic;
    }
    if (!m_config.tempTopic.isEmpty()) {
        topics << m_config.tempTopic;
    }
    
    if (!topics.isEmpty()) {
        subscribeTopics(topics);
    }
}

void MqttManager::onDisconnected()
{
    qDebug() << "已断开连接";
    
    stopHeartbeat();
    
    emit disconnected();
    emit connectionStatusChanged(getConnectionStatus());
    
    // 如果不是手动断开，且启用了自动重连，则启动重连
    if (!m_isManualDisconnect && m_config.autoReconnect) {
        qDebug() << "将在" << m_config.reconnectInterval << "秒后尝试重连...";
        startReconnect();
    }
}

void MqttManager::onReadyRead()
{
    QByteArray data = m_socket->readAll();
    QString text = QString::fromUtf8(data);
    
    m_receiveBuffer += text;
    
    // 处理所有完整的消息（以\r\n结尾）
    while (m_receiveBuffer.contains("\r\n")) {
        int pos = m_receiveBuffer.indexOf("\r\n");
        QString line = m_receiveBuffer.left(pos);
        m_receiveBuffer = m_receiveBuffer.mid(pos + 2);
        
        if (!line.isEmpty()) {
            m_receivedCount++;
            emit rawDataReceived(line);
            parseResponse(line);
            emit statisticsUpdated(m_sentCount, m_receivedCount);
        }
    }
}

void MqttManager::onError(QAbstractSocket::SocketError error)
{
    Q_UNUSED(error)
    
    m_lastError = m_socket->errorString();
    qDebug() << "Socket错误:" << m_lastError;
    
    emit errorOccurred(m_lastError);
    emit connectionStatusChanged(getConnectionStatus());
}

void MqttManager::onHeartbeatTimeout()
{
    if (isConnected()) {
        sendCommand(buildHeartbeatCmd());
    }
}

void MqttManager::onReconnectTimeout()
{
    stopReconnect();
    
    if (!isConnected() && !m_isManualDisconnect) {
        qDebug() << "尝试重新连接...";
        connectToServer(m_config);
    }
}

// Private methods implementation

void MqttManager::sendCommand(const QString &cmd)
{
    if (!isConnected()) {
        return;
    }
    
    QByteArray data = cmd.toUtf8();
    qint64 written = m_socket->write(data);
    m_socket->flush();
    
    if (written > 0) {
        m_sentCount++;
        qDebug() << "发送:" << cmd.trimmed();
        emit statisticsUpdated(m_sentCount, m_receivedCount);
    }
}

void MqttManager::parseResponse(const QString &response)
{
    qDebug() << "接收:" << response;
    
    // 解析键值对
    QMap<QString, QString> kvMap;
    parseKeyValue(response, kvMap);
    
    if (kvMap.isEmpty()) {
        return;
    }
    
    // 获取cmd字段
    QString cmd = kvMap.value("cmd");
    QString res = kvMap.value("res");
    QString topic = kvMap.value("topic");
    QString msg = kvMap.value("msg");
    QString uid = kvMap.value("uid");
    
    // 根据cmd类型处理
    if (cmd == "0" && res == "1") {
        // 心跳响应
        qDebug() << "心跳响应正常";
    }
    else if (cmd == "1" && res == "1") {
        // 订阅响应（优先判断res字段）
        qDebug() << "订阅成功";
        emit subscribeSuccess(topic);
    }
    else if (cmd == "1" && !res.isEmpty()) {
        // 订阅失败
        m_lastError = "订阅失败";
        emit errorOccurred(m_lastError);
    }
    else if (cmd == "2" && res == "1") {
        // 发布响应（优先判断res字段）
        qDebug() << "发布成功";
        emit publishSuccess(topic);
    }
    else if (cmd == "2" && !res.isEmpty()) {
        // 发布失败
        m_lastError = "发布失败";
        emit errorOccurred(m_lastError);
    }
    else if (cmd == "2" && !topic.isEmpty() && !msg.isEmpty()) {
        // cmd=2但有topic和msg，这是发布消息的回显或推送
        qDebug() << "收到消息推送 - 主题:" << topic << "内容:" << msg;
        emit messageReceived(topic, msg);
        
        // 解析设备控制消息
        if (topic == m_config.fanTopic || topic == m_config.fanTopic + "/set") {
            // 风扇控制消息
            if (m_config.parseModeMessage(msg)) {
                qDebug() << "模式改变:" << (m_config.manualMode ? "手动" : "自动");
                emit fanModeChanged(m_config.manualMode);
            }
            else if (m_config.parseFanSpeedMessage(msg)) {
                qDebug() << "风扇档位改变:" << m_config.fanSpeed;
                emit fanSpeedChanged(m_config.fanSpeed);
            }
        }
        else if (topic == m_config.tempTopic || topic == m_config.tempTopic + "/set") {
            // 温度数据消息
            if (m_config.parseTemperatureMessage(msg)) {
                qDebug() << "收到温度:" << m_config.temperature << "°C";
                emit temperatureReceived(m_config.temperature);
            }
        }
    }
    else if (cmd == "3" || cmd == "9") {
        // 历史消息响应
        if (!msg.isEmpty()) {
            qDebug() << "收到历史消息 - 主题:" << topic << "内容:" << msg;
            emit messageReceived(topic, msg);
        }
    }
    else if (cmd == "7") {
        // 服务器时间响应
        if (!msg.isEmpty()) {
            qDebug() << "服务器时间:" << msg;
            emit serverTimeReceived(msg);
        }
    }
    else if (!cmd.isEmpty() && !topic.isEmpty() && !msg.isEmpty()) {
        // 其他带topic和msg的消息推送
        qDebug() << "收到消息 - 主题:" << topic << "内容:" << msg;
        emit messageReceived(topic, msg);
        
        // 解析设备控制消息
        if (topic == m_config.fanTopic || topic == m_config.fanTopic + "/set") {
            // 风扇控制消息
            if (m_config.parseModeMessage(msg)) {
                qDebug() << "模式改变:" << (m_config.manualMode ? "手动" : "自动");
                emit fanModeChanged(m_config.manualMode);
            }
            else if (m_config.parseFanSpeedMessage(msg)) {
                qDebug() << "风扇档位改变:" << m_config.fanSpeed;
                emit fanSpeedChanged(m_config.fanSpeed);
            }
        }
        else if (topic == m_config.tempTopic || topic == m_config.tempTopic + "/set") {
            // 温度数据消息
            if (m_config.parseTemperatureMessage(msg)) {
                qDebug() << "收到温度:" << m_config.temperature << "°C";
                emit temperatureReceived(m_config.temperature);
            }
        }
    }
}

void MqttManager::parseKeyValue(const QString &data, QMap<QString, QString> &result)
{
    result.clear();
    
    QStringList pairs = data.split('&', QString::SkipEmptyParts);
    for (const QString &pair : pairs) {
        int pos = pair.indexOf('=');
        if (pos > 0) {
            QString key = pair.left(pos).trimmed();
            QString value = pair.mid(pos + 1).trimmed();
            result[key] = value;
        }
    }
}

void MqttManager::startHeartbeat()
{
    if (m_heartbeatTimer->isActive()) {
        m_heartbeatTimer->stop();
    }
    
    // 心跳间隔转换为毫秒
    int interval = m_config.heartbeatInterval * 1000;
    m_heartbeatTimer->start(interval);
    
    qDebug() << "启动心跳，间隔:" << m_config.heartbeatInterval << "秒";
}

void MqttManager::stopHeartbeat()
{
    if (m_heartbeatTimer->isActive()) {
        m_heartbeatTimer->stop();
        qDebug() << "停止心跳";
    }
}

void MqttManager::startReconnect()
{
    if (m_reconnectTimer->isActive()) {
        return;
    }
    
    int interval = m_config.reconnectInterval * 1000;
    m_reconnectTimer->start(interval);
}

void MqttManager::stopReconnect()
{
    if (m_reconnectTimer->isActive()) {
        m_reconnectTimer->stop();
    }
}

QString MqttManager::buildSubscribeCmd(const QStringList &topics)
{
    QString topicStr = topics.join(",");
    return QString("cmd=1&uid=%1&topic=%2\r\n")
            .arg(m_config.uid)
            .arg(topicStr);
}

QString MqttManager::buildPublishCmd(const QString &topic, const QString &msg)
{
    return QString("cmd=2&uid=%1&topic=%2&msg=%3\r\n")
            .arg(m_config.uid)
            .arg(topic)
            .arg(msg);
}

QString MqttManager::buildHistoryCmd(const QString &topic)
{
    return QString("cmd=9&uid=%1&topic=%2\r\n")
            .arg(m_config.uid)
            .arg(topic);
}

QString MqttManager::buildTimeCmd(int type)
{
    return QString("cmd=7&uid=%1&type=%2\r\n")
            .arg(m_config.uid)
            .arg(type);
}

QString MqttManager::buildHeartbeatCmd()
{
    return "ping\r\n";
}

